package judesart.app.client.ui.admin.profile;

import gwtupload.client.IUploader;
import gwtupload.client.MultiUploader;
import gwtupload.client.PreloadedImage;
import gwtupload.client.IFileInput.AnchorFileInput;
import gwtupload.client.IUploadStatus.Status;
import gwtupload.client.PreloadedImage.OnLoadPreloadedImageHandler;

import java.util.List;

import judesart.app.client.controller.ProfileController;
import judesart.app.client.controller.ProfileControllerAsync;
import judesart.app.client.widget.TopInfo;
import judesart.app.domain.Artist;
import judesart.app.domain.ArtistPhoto;

import com.allen_sauer.gwt.log.client.Log;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.IconButtonEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.widget.Composite;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.button.ToolButton;
import com.extjs.gxt.ui.client.widget.layout.ColumnLayout;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.AsyncCallback;

public class PhotosPanel extends Composite {
    ProfileControllerAsync profileController = GWT.create(ProfileController.class);

    // Load the image in the document and in the case of success attach it to
    // the viewer
    private final IUploader.OnFinishUploaderHandler onFinishUploaderHandler = new IUploader.OnFinishUploaderHandler() {
        public void onFinish(IUploader uploader) {
            if (uploader.getStatus() == Status.SUCCESS) {
                new PreloadedImage(uploader.fileUrl(), showImage);
                TopInfo.display("Info", "Upload : "
                        + uploader.getStatus().name());
                RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, "/commitimages");
                try {
                    builder.sendRequest(null, new RequestCallback() {

                        @Override
                        public void onResponseReceived(Request request,
                                Response response) {
                        }

                        @Override
                        public void onError(Request request, Throwable exception) {
                            Log.error("Error sending commit request", exception);
                            TopInfo.display("Error", "Unable to add images");
                        }
                    });
                } catch (RequestException e) {
                    Log.error("Error sending commit request", e);
                    TopInfo.display("Error", "Unable to add images");
                }
            }
        }
    };

    // A panel where the thumbnails of uploaded images will be shown
    private final LayoutContainer panelImages;

    private Artist artist;

    // Attach an image to the pictures viewer
    private final OnLoadPreloadedImageHandler showImage = new OnLoadPreloadedImageHandler() {
        public void onLoad(PreloadedImage image) {
            addImageToPanel(image);
        }
    };

    public PhotosPanel() {
        Log.debug("init Photos Panel");

        ContentPanel photosPanel = new ContentPanel();
        photosPanel.setHeading("Photos");
        photosPanel.setFrame(true);

        panelImages = new LayoutContainer();
        panelImages.setBorders(false);
        panelImages.setLayout(new ColumnLayout());
        panelImages.setStyleAttribute("margin-bottom", "30px");
        photosPanel.add(panelImages);

        MultiUploader defaultUploader = new MultiUploader();

        defaultUploader.addOnFinishUploadHandler(onFinishUploaderHandler);
        defaultUploader.setMaximumFiles(10);
        defaultUploader.setFileInputPrefix("default");
        defaultUploader.setServletPath("/upload");
        defaultUploader.avoidRepeatFiles(true);
        defaultUploader.setFileInput(new AnchorFileInput());

        photosPanel.add(defaultUploader);

        photosPanel.setSize("800px", "400px");

        initComponent(photosPanel);

        refresh();
    }

    public void refresh() {
        profileController.getArtist(new AsyncCallback<Artist>() {

            @Override
            public void onSuccess(Artist result) {
                Log.debug(" > success ");
                artist = result;
                if (artist.getPhotos() != null) {
                    Log.debug(" > success [" + artist.getPhotos() + "]");
                    List<ArtistPhoto> photos = artist.getPhotos();
                    for (ArtistPhoto photo : photos) {
                        String url = "/image?id=" + photo.getImageId()
                                + "&size=75x75&crop=true";
                        Log.debug(" > success image url [" + url + "]");
                        new PreloadedImage(url, photo.getImageId().toString(), "photo_"
                                + photo.getImageId(), showImage);
                    }
                }
            }

            @Override
            public void onFailure(Throwable caught) {
                TopInfo.display("Error", "Unable to get Artist information");
            }
        });
    }

    private void addImageToPanel(final PreloadedImage image) {
        image.setWidth("75px");
        final LayoutContainer imageContainer = new LayoutContainer();
        imageContainer.add(image);
        final ToolButton deletePhotoButton = new ToolButton(".x-tool-close");
        final Long artistId = artist.getId();
        deletePhotoButton.addListener(Events.Select,
                new Listener<IconButtonEvent>() {
                    public void handleEvent(IconButtonEvent e) {
                        imageContainer.setEnabled(false);
                        profileController.deletePhotoFromArtist(artistId,
                                new Long(image.getUniqId()),
                                new AsyncCallback<Void>() {
                                    @Override
                                    public void onFailure(Throwable caught) {
                                        TopInfo.display("Error",
                                                "Unable to delete image");
                                        imageContainer.setEnabled(true);
                                    }

                                    @Override
                                    public void onSuccess(Void result) {
                                        TopInfo.display("Info",
                                                "Image deleted succeffuly");
                                        imageContainer.setVisible(false);
                                    }
                                });
                    }
                });
        deletePhotoButton.setVisible(false);
        imageContainer.add(deletePhotoButton);
        final Timer hideDeletePhotoTime = new Timer() {
            @Override
            public void run() {
                deletePhotoButton.setVisible(false);
            }
        };
        image.addMouseOverHandler(new MouseOverHandler() {
            public void onMouseOver(MouseOverEvent event) {
                hideDeletePhotoTime.cancel();
                deletePhotoButton.setVisible(true);
            }
        });
        image.addMouseOutHandler(new MouseOutHandler() {
            public void onMouseOut(MouseOutEvent event) {
                hideDeletePhotoTime.schedule(2000);
            }
        });
        imageContainer.setWidth("95px");
        panelImages.add(imageContainer);
        panelImages.layout();
    }

}
